package visualcbir;

import java.awt.event.ActionEvent;
import visualcbir.visualstructures.VSRingsSpiral;
import visualcbir.visualstructures.VSSpiralCircle;
import visualcbir.visualstructures.VSRingsRings;
import visualcbir.visualstructures.VSRingsCircle;
import visualcbir.visualstructures.VSSpiralSpiral;
import visualcbir.visualstructures.VSSpiralRings;
import visualcbir.visualstructures.VSGrid;
import visualcbir.decorators.FunOptions;
import java.util.logging.Level;
import java.util.logging.Logger;
import visualcbir.cluster.VSCircleSpiral;
import visualcbir.cluster.VSCircle;
import visualcbir.cluster.VSCircleRings;
import visualcbir.decorators.FunZoom;
import iautils.IAUtils;
import javax.swing.event.ChangeEvent;
import visualcbir.gui.ToolBarNorth;
import visualcbir.gui.MenuBarSelf;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JViewport;
import javax.swing.event.ChangeListener;
import visualcbir.util.VSUtils;
import visualcbir.cluster.VSCircleCircle;
import visualcbir.visualstructures.ring.VSRings;
import visualcbir.visualstructures.spiral.VSSpiral;

/**
 *
 * @author sheila
 */

public class Principal extends JFrame {
    private JPanel oPnlZoom, oPnlOptions;
    private PnlView pvRings,pvSpiral,pvGrid, pvCircle,
        pvCircleRings, pvCircleSpiral, pvCircleCircle,
        pvSpiralRings, pvSpiralSpiral,pvSpiralCircle,
        pvRingsRings, pvRingsSpiral, pvRingsCircle;
    //public PnlViewDynamic pvDynamic;
    private ModelComposedSimple oModelComposedSimple;
    private ModelComposedGroups oModelClusters;
    
    private Principal() {
        try {
            oPnlZoom = new JPanel();
            oPnlOptions = new JPanel();
            initComponents();
            
        } catch (NoSuchFieldException ex) {
            Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void initComponents() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException{
        oModelComposedSimple=new ModelComposedSimple();
        oModelClusters = new ModelComposedGroups();        
        oModelComposedSimple.getData(500,35);//s/
        oModelClusters.getData(500,60,15,null);//when changing the thrid parameter, change also the desired view  to display such a number of elements.
        
        //oModelClusters.getData(20);

        Container cp=this.getContentPane();
        cp.setLayout(new BorderLayout());

        System.out.println("--------------------VSGRID--------------------");
        pvGrid = new PnlView(new VSGrid(oModelComposedSimple,36));
        System.out.println("--------------------VSRING--------------------");
        pvRings = new PnlView(new VSRings(oModelComposedSimple,36));
        System.out.println("--------------------VSSPIRAL--------------------");
        pvSpiral = new PnlView(new VSSpiral(oModelComposedSimple,36));
        System.out.println("--------------------VSCIRCLE--------------------");
        pvCircle= new PnlView(new VSCircle(oModelComposedSimple,16));

        System.out.println("--------------------VSClusteringSet--------------------");
        pvCircleCircle = new PnlView(new VSCircleCircle(oModelClusters,6));        
        System.out.println("--------------------VSClusterRings--------------------");
        pvCircleRings = new PnlView(new VSCircleRings(oModelClusters,10));
        System.out.println("--------------------VSClusterSpiral--------------------");
        pvCircleSpiral = new PnlView(new VSCircleSpiral(oModelClusters,10));

        pvRingsRings = new PnlView(new VSRingsRings(oModelClusters,15));
        pvRingsSpiral = new PnlView(new VSRingsSpiral(oModelClusters,10));
        pvRingsCircle = new PnlView(new VSRingsCircle(oModelClusters,14));
        pvSpiralRings = new PnlView(new VSSpiralRings(oModelClusters,14));
        pvSpiralSpiral = new PnlView(new VSSpiralSpiral(oModelClusters,13));
        pvSpiralCircle = new PnlView(new VSSpiralCircle(oModelClusters,12));

        //pvDynamic = new PnlViewDynamic(new VSDynamic(oModelComposedSimple,20));
  
        JTabbedPane jtp = new JTabbedPane();

        String[] aStrVisibleNames = {"Grid","Concentric Rings","Spiral","Circle","Clustering Set","Clus.Set-Rings",
        "Clus.Set-Spiral","Rings-Rings","Rings-Spiral","Rings-Circle","Spiral-Rings","Spiral-Spiral","Spiral-Circle"};
        String[] aStrRealNames = {"Grid","Rings","Spiral","Circle","CircleCircle","CircleRings",
        "CircleSpiral","RingsRings","RingsSpiral","RingsCircle","SpiralRings","SpiralSpiral","SpiralCircle"};

        for (int i = 0; i < aStrRealNames.length; i++) {
            String oPnlViewName= "pv"+aStrRealNames[i];
            Field field = this.getClass().getDeclaredField(oPnlViewName);// getDeclaredField acess private fiels of this class. getfield doesn't allow.
            jtp.addTab(aStrVisibleNames[i], new JScrollPane(  (PnlView)field.get(this) ) );
        }
        
        //jtp.addTab("Dynamic", new JScrollPane(pvDynamic));
        jtp.setTabPlacement(JTabbedPane.TOP);
        jtp.addChangeListener(new LsnChange());
        jtp.setSelectedIndex(0);
        //******************************** final button to process all
        JButton btnProcess = new JButton("Process Query");
        btnProcess.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                //oPnlOptions.
            }
        });
        //********************************

        PnlControls oPnlControls=new PnlControls();
        oPnlControls.setLayout(new BoxLayout(oPnlControls, BoxLayout.Y_AXIS));
        oPnlControls.addComponent(new PnlImage(this));
        oPnlControls.addComponent(oPnlZoom);
        oPnlControls.addComponent(oPnlOptions);
        //oPnlControls.addComponent(btnProcess);

        //********** Adding elements to the Frame ****************************//
        this.setJMenuBar(new MenuBarSelf());
        cp.add(new ToolBarNorth(), BorderLayout.NORTH);
        cp.add(jtp,BorderLayout.CENTER);

        cp.add(oPnlControls, BorderLayout.WEST);
        
        this.setTitle("Visualization CBIR Toolkit");                
    }
    
    public void updateQueryImage(String imgPath){
        String imagesPaths = VSUtils.getProperty("imagespaths");
        int imgID=IAUtils.searchIdImageByPath(imgPath,imagesPaths);
               
        clearall();        
        //System.gc();//clear listeners adicionados ao painel

        System.out.println("-----------imgID"+imgID);
        oModelComposedSimple.getData(imgID,35);
        oModelClusters.getData(imgID,60,6,null);

        pvGrid.setNewView(new VSGrid(oModelComposedSimple, ((FunOptions)pvGrid.getFunctionality("Options")).getNumImages() ));
        pvRings.setNewView(new VSRings(oModelComposedSimple,36));
        pvSpiral.setNewView(new VSSpiral(oModelComposedSimple,36));
        pvCircle.setNewView(new VSCircle(oModelComposedSimple,16));

        pvCircleCircle.setNewView(new VSCircle(oModelClusters,7));
        pvCircleRings.setNewView(new VSCircleRings(oModelClusters,7));
        pvCircleSpiral.setNewView(new VSCircleSpiral(oModelClusters,7));

        pvRingsRings.setNewView(new VSRingsRings(oModelClusters,7));
        pvRingsSpiral.setNewView(new VSRingsSpiral(oModelClusters,7));
        pvRingsCircle.setNewView(new VSRingsCircle(oModelClusters,7));
        pvSpiralRings.setNewView(new VSSpiralRings(oModelClusters,7));
        pvSpiralSpiral.setNewView(new VSSpiralSpiral(oModelClusters,10));
        pvSpiralCircle.setNewView(new VSSpiralCircle(oModelClusters,7));

        pvGrid.repaint();
        pvRings.repaint();
        pvSpiral.repaint();
        pvCircle.repaint();
        pvCircleCircle.repaint();
        pvCircleRings.repaint();
        pvCircleSpiral.repaint();
        pvRingsRings.repaint();
        pvRingsSpiral.repaint();
        pvRingsCircle.repaint();
        pvSpiralRings.repaint();
        pvSpiralSpiral.repaint();
        pvSpiralCircle.repaint();        
    }
    
    public void clearall(){
        oModelComposedSimple.clearModel();
        oModelClusters.clearModel();
    }

    PnlView oPnlCurrent;
    public class LsnChange implements ChangeListener{        
        @Override
        public void stateChanged(ChangeEvent e) {
            JScrollPane jscrollpane = (JScrollPane)((JTabbedPane)e.getSource()).getSelectedComponent();
            Component pnl =  ((JViewport)jscrollpane.getComponent(0)).getComponent(0);
            oPnlCurrent = (PnlView)pnl;
            updateFunctions(oPnlCurrent);
        }
    }

    public void updateFunctions(PnlView oPnlView){
        oPnlZoom.removeAll();
        if(oPnlView.getFunctionality("Zoom") != null){
            oPnlZoom.add(((FunZoom)oPnlView.getFunctionality("Zoom")).getPnl());
            oPnlZoom.updateUI();
        }

       oPnlOptions.removeAll();
        if(oPnlView.getFunctionality("Options") != null){
            oPnlOptions.add(((FunOptions)oPnlView.getFunctionality("Options")).getPnl());
            oPnlOptions.updateUI();
        }
    }

//    public void getFeatureFromFunctionality(String funtion){
//        oPnlView.getFunctionality(function)
//    }

    public JComponent getCurrentComponent(){
        return this.oPnlCurrent;
    }

// ***************************************************************************//
//                          Singleton
// ***************************************************************************//
    private static Principal instance=null;
    
    public static Principal getInstance(){
        if(instance == null)
            instance=new Principal();
        return instance;
    }

    public static void main(String[] args) {
        Principal.getInstance().setSize(1000,800);   //ao finalizar implementacao comentar esta linha
        Principal.getInstance().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Principal.getInstance().setVisible(true);
        //Principal.getInstance().setExtendedState(JFrame.MAXIMIZED_BOTH);
    }
}